package postgres

import (
	"context"
	"gorm.io/gorm"
	"manager/errors"
	"manager/model"
	"manager/model/entity"
)

var FirstFaultType = &firstFaultType{}

type firstFaultType struct{}

// Create 创建
func (a *firstFaultType) Create(ctx context.Context, m *entity.FirstFaultType) (int64, error) {
	err := GetDB(ctx).Create(m).Error
	return m.Id, err
}

// Find 查找详情
func (a *firstFaultType) Find(ctx context.Context, in *model.FirstFaultTypeInfoRequest) (*entity.FirstFaultType, error) {
	e := &entity.FirstFaultType{}

	q := GetDB(ctx).Model(&entity.FirstFaultType{})

	if in.Id > 0 {
		err := q.First(&e, in.Id).Error
		return e, err
	}

	count := 0

	if in.Name != nil {
		q = q.Where("name = ?", in.Name)
		count++
	}

	if in.Desc != nil {
		q = q.Where("desc = ?", in.Desc)
		count++
	}

	if in.UpdatedAt != nil {
		q = q.Where("updated_at = ?", in.UpdatedAt)
		count++
	}

	if count == 0 {
		return e, errors.New("condition illegal")
	}

	err := q.First(&e).Error
	return e, err
}

// Update 更新
func (a *firstFaultType) Update(ctx context.Context, id int64, dict map[string]interface{}) error {
	return GetDB(ctx).Model(&entity.FirstFaultType{}).Where("id = ?", id).Updates(dict).Error
}

// Delete 删除
func (a *firstFaultType) Delete(ctx context.Context, id int64) error {
	return GetDB(ctx).Delete(&entity.FirstFaultType{}, id).Error
}

// List 列表查询
func (a *firstFaultType) List(ctx context.Context, in *model.FirstFaultTypeListRequest) (int, []*entity.FirstFaultType, error) {
	var (
		q               = GetDB(ctx).Model(&entity.FirstFaultType{})
		err             error
		total           int64
		firstFaultTypes []*entity.FirstFaultType
	)

	if len(in.Ids) > 0 {
		q = q.Where("id IN (?)", in.Ids)
	}

	if in.Name != nil {
		q = q.Where("name = ?", in.Name)
	}

	if in.Desc != nil {
		q = q.Where("desc = ?", in.Desc)
	}

	if in.UpdatedAt != nil {
		q = q.Where("updated_at = ?", in.UpdatedAt)
	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Order("created_at desc").Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&firstFaultTypes).Error; err != nil {
		return 0, nil, err
	}

	// 获取孩子节点数据
	type ret struct {
		FirstType int64 `gorm:"column:first_type;type:BIGINT" json:"first_type"`
		Count     int64 `json:"count"`
	}
	var rets []*ret
	err = GetDB(ctx).Model(&entity.FaultType{}).Select("first_type, count(*)").Group("first_type").Scan(&rets).Error
	if err == nil {
		faultTypeCountMap := map[int64]int64{}
		for i := 0; i < len(rets); i++ {
			faultTypeCountMap[rets[i].FirstType] = rets[i].Count
		}

		// 是否有孩子
		for i := 0; i < len(firstFaultTypes); i++ {
			if v, ok := faultTypeCountMap[firstFaultTypes[i].Id]; ok {
				firstFaultTypes[i].HasChild = v > 0
			}
		}
	}

	return int(total), firstFaultTypes, nil
}

// ExecTransaction db事务执行
func (a *firstFaultType) ExecTransaction(ctx context.Context, callback func(ctx context.Context) error) error {
	return GetDB(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, DBCONTEXTKEY, tx)
		return callback(ctx)
	})
}
